﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EntitiesLayer;
using DAL.Repositories;
using System.Transactions;
using System.Data.SqlClient;
using System.Data;


namespace DAL.Repositories
{
    internal class SateliteRepository :IRepository<Satelite>
    {
        private IList<IEntity> insertedList;
        private IList<IEntity> updatedList;
        private IList<IEntity> deletedList;

        internal SateliteRepository() {

            insertedList = new List<IEntity>();
            updatedList = new List<IEntity>();
            deletedList = new List<IEntity>();
        }

        public void Insert(Satelite entity)
        {
            insertedList.Add(entity);
        }

        public void Delete(Satelite entity)
        {
            deletedList.Add(entity);
        }

        public void Update(Satelite entity)
        {
            updatedList.Add(entity);            
        }

        public IEnumerable<Satelite> GetAll()
        {
            
             SqlCommand cmd = new SqlCommand();
             DataSet ds = DBAccess.ExecuteSPWithDS(ref cmd, "pa_listar_satelites");
    

            foreach (DataRow dr in ds.Tables[0].Rows)
                yield return crearSatelite(dr, Convert.ToInt32(dr["IDSATELITE"]));


        }

        public Satelite GetById(int id)
        {
            Satelite objSatelite = null;
            SqlCommand cmd = new SqlCommand();
            cmd.Parameters.Add(new SqlParameter("@idSatelite", id));
            DataSet ds = DBAccess.ExecuteSPWithDS(ref cmd, "Pa_consultar_satelite_por_id");

            foreach (DataRow dr in ds.Tables[0].Rows)
                objSatelite = crearSatelite(dr, id);
            

            return objSatelite;
            
        }

        public void Save()
        {
            using (TransactionScope scope = new TransactionScope())
            {

                try
                {

                    foreach (Satelite p in insertedList)
                        InsertSatelite(p);

                    foreach (Satelite p in updatedList)
                        UpdateSatelite(p);

                    foreach (Satelite p in deletedList)
                        DeleteSatelite(p);


                    scope.Complete();
                }
                catch (TransactionAbortedException ex)
                {
                    Console.WriteLine(ex.Message);
                    throw ex;
                }
                catch (ApplicationException ex)
                {
                    Console.WriteLine(ex.Message);
                    throw ex;
                }
                finally
                {
                    Clear();
                }

            }
        }

        public void Clear()
        {
            insertedList.Clear();
            updatedList.Clear();
            deletedList.Clear();
        }
        #region Utilities
        private void InsertSatelite(Satelite objSatelite){

            try
            {
                SqlCommand cmd = new SqlCommand();
                cmd.Parameters.Add(new SqlParameter("@nombre", objSatelite.Nombre));
                cmd.Parameters.Add(new SqlParameter("@masa", objSatelite.Masa));
                cmd.Parameters.Add(new SqlParameter("@temp", objSatelite.TemperaturaMedia));
                cmd.Parameters.Add(new SqlParameter("@duracion", objSatelite.Duracion.Ticks));
                cmd.Parameters.Add(new SqlParameter("@caracteristicas", objSatelite.Caracteristicas));
                cmd.Parameters.Add(new SqlParameter("@DistanciaPlaneta", objSatelite.DistanciaPlaneta));
                cmd.Parameters.Add(new SqlParameter("@IdPlaneta", objSatelite.IdPlaneta));

                DataSet ds = DBAccess.ExecuteSPWithDS(ref cmd, "pa_RegistrarSatelite");
            }
            catch (SqlException ex) {
                Console.WriteLine(ex.Message);
                throw ex;
            }
            
        }

        private void UpdateSatelite(Satelite objSatelite)
        {
            throw new NotImplementedException();

        }

        private void DeleteSatelite(Satelite objSatelite)
        {
            throw new NotImplementedException();

        }

        internal static Satelite crearSatelite(DataRow dr, int id)
        {
            Console.WriteLine("Id: " + id + "is idplaneta" + (dr["IDPLANETA"] == DBNull.Value));

            Satelite objSatelite = new Satelite(
            
                    id: id,
                    nombre: dr["NOMBRE"].ToString(),
                    masa: Convert.ToDecimal(dr["MASA"]),
                    duracion: new TimeSpan(Convert.ToInt64(dr["DURACIONDIA"])),
                    caracteristicas: dr["CARACTERISTICAS"].ToString(),
                    temperaturaMedia: Convert.ToDecimal(dr["TEMPMEDIA"]),
                    distanciaPlaneta: Convert.ToDecimal(dr["DISTANCIAPLANETA"]),
                    idPlaneta: Convert.ToInt32(dr["IDPLANETA"]),
                    missionDelegate: new Lazy<IList<Mission>>(() => { 
                        return MissionRepository.consultarMissionesCuerpoCeleste(id); 
                    })

                );

            return objSatelite;

        }

        #endregion Utilities
    }
}
